package patternmining.model.construction;

import java.util.EnumMap;
import java.util.Map;

/** Definition of the domains associated to each predicate type in the BPSL formalism.
 *
 * @author Holger
 */
class BPSLPredicateSpace {
    private Map<BPSLPredicateType, BPSLTermType[][]> predicates;
    
    private static BPSLPredicateSpace instance;
    
    private BPSLPredicateSpace(){
        predicates = new EnumMap<BPSLPredicateType, BPSLTermType[][]>( BPSLPredicateType.class );
	// define domain of predicate "Defined-in" : MxC , TxC
        predicates.put( BPSLPredicateType.DefinedIn, new BPSLTermType[][]{ {BPSLTermType.METHOD, BPSLTermType.CLASS}, {BPSLTermType.TYPEDVARIABLE, BPSLTermType.CLASS} });
        // define domain of predicate "Reference-to-on" : CxC
	predicates.put( BPSLPredicateType.ReferenceToOne, new BPSLTermType[][]{ {BPSLTermType.CLASS, BPSLTermType.CLASS} });
        // define domain of predicate "Reference-to-many" : CxC
	predicates.put( BPSLPredicateType.ReferenceToMany, new BPSLTermType[][]{ {BPSLTermType.CLASS, BPSLTermType.CLASS} });
        // define domain of predicate "Inheritance" : CxC
	predicates.put( BPSLPredicateType.Inheritance, new BPSLTermType[][]{ {BPSLTermType.CLASS, BPSLTermType.CLASS} }); 
        // define domain of predicate "Creation" : MxC, CxC
	predicates.put( BPSLPredicateType.Creation, new BPSLTermType[][]{ {BPSLTermType.METHOD, BPSLTermType.CLASS}, {BPSLTermType.CLASS, BPSLTermType.CLASS} });
        // define domain of predicate "Invocation" : MxM, CxM, MxC, CxC
	predicates.put( BPSLPredicateType.Invocation, new BPSLTermType[][]{ {BPSLTermType.METHOD, BPSLTermType.METHOD}, {BPSLTermType.CLASS, BPSLTermType.METHOD}, {BPSLTermType.METHOD, BPSLTermType.CLASS}, {BPSLTermType.CLASS, BPSLTermType.CLASS} }); 
         // define domain of predicate "Argument" : CxM, VxM
	predicates.put( BPSLPredicateType.Argument, new BPSLTermType[][]{ {BPSLTermType.CLASS, BPSLTermType.METHOD}, {BPSLTermType.TYPEDVARIABLE, BPSLTermType.METHOD} });
         // define domain of predicate "Return-type" : CxM
	predicates.put( BPSLPredicateType.ReturnType, new BPSLTermType[][]{ {BPSLTermType.CLASS, BPSLTermType.METHOD} });
        
    }
    
    public static BPSLPredicateSpace getInstance(){
        if ( instance == null ){
            instance = new BPSLPredicateSpace();
        }
        return instance;
    }
	
    public boolean isDefinedOnDomain(String predicate, BPSLTermType term1, BPSLTermType term2){
        BPSLTermType[][] temp = predicates.get( BPSLPredicateType.getEnum(predicate));
        boolean ok = false;
        if ( temp != null ) {
            int pos = 0;
            while ( ! ok && pos < temp.length ){
                if( temp[pos][0] == term1 && temp[pos][1] == term2 )  ok = true;
                else  pos++;
            }
        }
        return ok;
    }
		
    public boolean isDefined(String predicate){
        return predicates.containsKey( BPSLPredicateType.getEnum(predicate));	
    }
	
}
